import typeOfUtils from "../../../utils/type-of-utils";
import RenderUtils from "../RenderUtils";
import {RenderTypeItem} from "../ConfigType";

const select: RenderTypeItem = {
  slotNames: ['prefix', 'empty', 'default'],
  name: 'select',
  /**
   * 初始化自己的绑定值
   * @param vm
   * @param formItem
   */
  initFormValue(vm, formItem) {
    // @ts-ignore
    if (formItem.props.multiple) {
      vm.$set(vm.formData, formItem.prop, [])
    } else {
      vm.$set(vm.formData, formItem.prop, undefined)
    }
  },
  /**
   * @param vm
   * @param formItem
   */
  initFormItem(vm, formItem) {
    // @ts-ignore
    if (typeOfUtils.isEmpty(formItem.props.options)) {
      vm.$set(formItem.props, 'options', [])
    }
    // @ts-ignore
    if (typeOfUtils.isFunction(formItem.props.asyncSetOptions)) {
      vm.$set(formItem.props, 'loading', true)
      // @ts-ignore
      formItem.props.asyncSetOptions().then(res => {
        vm.$set(formItem.props, 'options', res)
      }).finally(() => {
        // @ts-ignore
        formItem.props.loading = false
      })
    }
  },
  /**
   * 异步加载
   * @param formItem
   * @param vm
   * @param query
   */
  asyncSetOptions(formItem, vm, query) {
    if (typeOfUtils.isFunction(formItem.props.asyncSetOptions)) {
      formItem.props.loading = true
      formItem.props.asyncSetOptions(query).then(res => {
        vm.$set(formItem.props, 'options', res)
      }).finally(() => {
        formItem.props.loading = false
      })
    }
  },
  /**
   *
   * @param createElement
   * @param vm
   * @param formItem
   * @return {VNode[]}
   */
  render(createElement, vm, formItem) {
    const props = {
      label: formItem.props?.props?.label || 'label',
      value: formItem.props?.props?.value || 'value',
      children: formItem.props?.props?.children || 'children',
    }
    const options = RenderUtils.getItemPropsOptions(formItem)
    // 修改远程搜索
    // @ts-ignore
    if (formItem.props.filterable && formItem.props.remote) {
      // @ts-ignore
      formItem.props.remoteMethod = (query) => {
        this.asyncSetOptions(formItem, vm, query)
      }
    }
    const config = RenderUtils.getConfig(vm, formItem, {
      props: {
        placeholder: '请选择' + formItem.label,
      },
      on: {
        change: async (val) => {
          if (typeOfUtils.isFunction(formItem.events?.change)) {
            // @ts-ignore
            await formItem.events.change(options, val)
          }
          vm.$emit('selectChange', formItem.prop, vm.formData, {type: this.name, options})
        },
        focus: (e) => {
          if (typeOfUtils.isFunction(formItem.events?.focus)) {
            // @ts-ignore
            formItem.events.focus(options, e)
          }
          // @ts-ignore
          if (typeOfUtils.isFunction(formItem.props.focusLoadAgain)) {
            // @ts-ignore
            if (formItem.props.focusLoadAgain()) {
              this.asyncSetOptions(formItem, vm)
            }
          }
        }
      },
    }, this)
    const children = RenderUtils.renderSlotsChildren(formItem, createElement, this.slotNames, vm)
    // @ts-ignore
    children.push(...this.renderOptions(options, createElement, props, vm, formItem))
    return [
      createElement(`el-select`, config, children)
    ]
  },
  /**
   *
   * @param options
   * @param h
   * @param props
   * @param vm
   * @return {VNode[]}
   */
  renderChildren(options = [], h, props, vm) {
    const children = []
    options.forEach(i => {
      // @ts-ignore
      children.push(h('el-option', {
        props: {
          // @ts-ignore
          ...i,
          label: i[props.label],
          value: i[props.value],
          disabled: RenderUtils.setOptionsDisabled(i, vm)
        }
      }))
    })
    return children
  },
  /**
   * 如果有children就分组
   * @param options
   * @param h
   * @param props
   * @param vm
   * @param formItem
   * @return {VNode[]}
   */
  renderOptions(options = [], h, props, vm, formItem) {
    const children = []
    options.forEach(i => {
      if (typeOfUtils.isNotEmpty(i[props.children]) && formItem.props?.group) {
        // @ts-ignore
        children.push(h('el-option-group', {
          props: {
            // @ts-ignore
            ...i,
            label: i[props.label],
            disabled: RenderUtils.setOptionsDisabled(i, vm)
          }
        }, this.renderChildren(i[props.children], h, props, vm)))
      } else {
        // @ts-ignore
        children.push(h('el-option', {
          props: {
            // @ts-ignore
            ...i,
            label: i[props.label],
            value: i[props.value],
            disabled: RenderUtils.setOptionsDisabled(i, vm)
          }
        }))
      }
    })
    return children
  }
}
export default select
